/*
 * File:   dataProc.h
 * Author: aple
 *
 * Created on 2014年9月15日, 下午8:29
 */

#ifndef DATAPROC_H
#define DATAPROC_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "stdint.h"
#include "stdlib.h"
#include "string.h"
#include "mytype.h"

#define DATA_PROC_ERR_NONE 0x0
#define DATA_PROC_ERR_RES 0x21

	/*******************************************************************************
	 * @brief  speed calculate
	 *******************************************************************************/
#define uspr_with_speed(speed) ((60UL * 1000000UL + ((speed) >> 1)) / (speed))					  // 输入转速rpm， 返回每转us数
#define us20pr_with_speed(speed) ((60UL * 1000000UL + ((20 * (speed)) >> 1)) / (20 * (speed)))	  // 输入转速rpm， 返回每转20us数
#define us50pr_with_speed(speed) ((60UL * 1000000UL + ((50 * (speed)) >> 1)) / (50 * (speed)))	  // 输入转速rpm， 返回每转50us数
#define us100pr_with_speed(speed) ((60UL * 1000000UL + ((100 * (speed)) >> 1)) / (100 * (speed))) // 输入转速rpm， 返回每转100us数
#define rpm_with_us(us) ((60UL * 1000000UL + ((us) >> 1)) / (us))								  // 输入每转us数， 返回转速rpm
#define rpm_m10_with_us(us) ((600UL * 1000000UL + ((us) >> 1)) / (us))							  // 输入每转us数， 返回转速10*rpm
#define rpm_with_clk(clk, cnt) ((60UL * (clk) + ((cnt) >> 1)) / (cnt))							  // 输入clk为计数频率(应保证60*clk<2^32)，cnt为每转计数值， 返回转速rpm
#define rpm_m10_with_clk(clk, cnt) ((600UL * (clk) + ((cnt) >> 1)) / (cnt))						  // 输入clk为计数频率(应保证60*clk<2^32)，cnt为每转计数值， 返回转速10*rpm

	/*******************************************************************************
	 * @brief  简易逻辑运算
	 *******************************************************************************/
#define logic_alloc() static uint8_t logic_handle_data
#define logic_and_init() logic_handle_data = 1
#define logic_or_init() logic_handle_data = 0
#define logic_and(x) logic_handle_data = logic_handle_data && (x)
#define logic_or(x) logic_handle_data = logic_handle_data || (x)
#define logic_not() logic_handle_data = !logic_handle_data
#define logic_get() logic_handle_data

	// logic calculate
#define lgc_new(x)			if((x)
#define lgc_next(x)			else if((x)
#define lgc_and(x) &&(x)
#define lgc_or(x) || (x)
#define lgc_exe()			)

	/*******************************************************************************
	 * @brief  const dat
	 *******************************************************************************/
	extern uint8_t const led_code[];
	extern uint8_t const ascii_code[];

	// 0-256*4
	extern const uint8_t sinx_0r5pi_256_255[];
	ii16 sinx_0r5pi_256_255_get(ii16 angle);
	ii16 cosx_0r5pi_256_255_get(ii16 angle);

	// 0-2048*4
	extern ii16 const sinx_0r5pi_2048_16384[];
	ii16 sinx_0r5pi_2048_16384_get(ii16 angle);
	ii16 cosx_0r5pi_2048_16384_get(ii16 angle);

	extern uint16_t const sinx2_0r5pi_2048_16384[];
	extern const uint8_t sinx2_0r5pi_256_255[];

	// 0-900*4
	extern const short sinx_0r5pi_900_10000[];
	ii16 sinx_0r5pi_900_10000_get(ii16 angle);
	ii16 cosx_0r5pi_900_10000_get(ii16 angle);

	extern const uu16 sinx2_integral_pi_1000[];
	uu32 sinx2_integral_pi_1000_get_angle(uu16 integral, uu16 coef_x1000);

	extern const float sinx2_integral_pi_1000_f[];
	float sinx2_integral_pi_1000_f_get_angle(float integral);

	extern const char hex_ascii_h_tab[];
	extern const char hex_ascii_l_tab[];

	extern const uint8_t prime_b8[54];
	extern const uint16_t prime_b9[97];
	extern const uint16_t prime_b10[172];
	extern const uint16_t prime_b11[309];
	extern const uint16_t prime_b12[564];
	extern const uint16_t prime_b13[1028];
	extern const uint16_t prime_b14[1900];
	extern const uint16_t prime_b15[3512];
	extern const uint16_t prime_b16[6542];

	extern const char asc_pic_bat[];
	extern const char asc_pic_fo[];
	extern const char asc_pic_key[];
	extern const char asc_pic_girl[];
	extern const char asc_pic_shuai_cong[];
	extern const char asc_pic_shuai_cong2[];
	extern const char asc_pic_aple0807[];
	extern const char asc_pic_bat2[];
	extern const char asc_pic_bear[];
	extern const char asc_pic_fly[];
	extern const char asc_pic_light[];
	extern const char asc_pic_lights[];
	extern const char asc_pic_asctab[];
	extern const char asc_pic_ball[];

	/*****************************************************************************
	 * @brief  死区.
	 *****************************************************************************/
	int32_t dead_zone(int32_t val_real, int32_t val_now, int32_t dead_zone);

	/*****************************************************************************
	 * @brief  bcd 转换.
	 * \retval: none 、dat
	 *****************************************************************************/
	void Hex4ToBCD4(uint16_t Data, uint8_t *Des);
	void Hex4ToBCD8(uint16_t Data, uint8_t *Des);
	void Hex2ToBCD2(uint8_t Data, uint8_t *Des);
	void Hex2ToBCD4(uint8_t Data, uint8_t *Des);

	uint8_t BCD2ToHex(uint8_t Data, uint8_t *Des);
	uint8_t BCD4ToHex(uint16_t Data, uint8_t *Des);
	uint8_t BCD8ToHex(uint32_t Data, uint8_t *Des);

	uint8_t bcd_to_hex_u8(uint8_t bcd);
	uint16_t bcd_to_hex_u16(uint16_t bcd);
	uint32_t bcd_to_hex_u32(uint32_t bcd);

	uint8_t hex_to_bcd_u8(uint8_t dat);
	uint16_t hex_to_bcd_u16(uint16_t dat);
	uint32_t hex_to_bcd_u32(uint32_t dat);

	void hex_to_bcd_s(const uu08 *hex, uu08 *bcd, int len);
	void bcd_to_hex_s(const uu08 *bcd, uu08 *hex, int len);
	/*******************************************************************************
	 * @brief   非压缩BCD转为压缩BCD, 非压缩BCD的低字节为压缩BCD的高半字节
	 *******************************************************************************/
	void bcd_zip(const void *unzip, void *zip, int zip_len);

	/*******************************************************************************
	 * @brief   压缩BCD转为非压缩BCD, 非压缩BCD的低字节为压缩BCD的高半字节
	 *******************************************************************************/
	void bcd_unzip(const void *zip, void *unzip, int zip_len);

	/*******************************************************************************
	 * @brief  Hex ascii translate
	 *******************************************************************************/
	void hex8_to_ascii(uint32_t Num, uint8_t *Des); // 尾部加 0
	void hex4_to_ascii(uint16_t Num, uint8_t *Des); // 尾部加 0
	void hex2_to_ascii(uint8_t Num, uint8_t *Des);	// 尾部加 0

	char hex_to_ascii_lo(uint8_t dat);
	char hex_to_ascii_ho(uint8_t dat);

	// len 指定hex长度，尾部加 0
	size_t hex2_to_ascii_multi(const uint8_t *hex, char *ascii, size_t len);
	size_t hex2_to_ascii_multi_ext(const uint8_t *hex, char *ascii, size_t len, const char *prefix, const char *suffix);

	// 遇到非法字符退出， len_max指定最大hex2数量，返回实际转换的hex数量
	size_t ascii_to_hex2_multi(const char *ascii, uint8_t *hex, size_t len_max);

	// 遇到0退出，跳过非法字符，len_max指定最大hex2数量，返回实际转换的hex数量
	size_t str_to_hex2(const char *str, uint8_t *hex, size_t len_max);

	// 一个HEX字符转换为对应的数值
	uint8_t ascii_to_hex(uint8_t ascii);

	// ascii 码转值
	uint8_t ascii_to_hex2(uint8_t *Src);  // 2B ascii
	uint16_t ascii_to_hex4(uint8_t *Src); // 4B ascii
	uint32_t ascii_to_hex8(uint8_t *Src); // 8B ascii

	/*******************************************************************************
	 * @brief  数据位段截取 - 用于安全相关禁止出现数据表的场合
	 *******************************************************************************/
	uint32_t code_set_lb(uint32_t src, uint8_t lb);
	uint32_t code_set_hb(uint32_t src, uint8_t hb);
	uint32_t code_set_ub(uint32_t src, uint8_t ub);
	uint32_t code_set_mb(uint32_t src, uint8_t mb);
	uint8_t code_get_lb(uint32_t src);
	uint8_t code_get_hb(uint32_t src);
	uint8_t code_get_ub(uint32_t src);
	uint8_t code_get_mb(uint32_t src);
	uint8_t code_add_u8(uint8_t u1, uint8_t u2);
	uint16_t code_add_u16(uint16_t u1, uint16_t u2);
	uint32_t code_add_u32(uint32_t u1, uint32_t u2);
	uint8_t code_add3_u8(uint8_t u1, uint8_t u2, uint8_t u3);
	uint16_t code_add3_u16(uint16_t u1, uint16_t u2, uint16_t u3);
	uint32_t code_add3_u32(uint32_t u1, uint32_t u2, uint32_t u3);
	uint8_t code_sub_u8(uint8_t u1, uint8_t u2);
	uint16_t code_sub_u16(uint16_t u1, uint16_t u2);
	uint32_t code_sub_u32(uint32_t u1, uint32_t u2);

	/*******************************************************************************
	 * @brief  获取2的n次方边界值
	 *******************************************************************************/
	uint32_t get_2n_alain_val(uint32_t val);

	/*****************************************************************************
	 *          转换结果右对齐，无论是否消零都占用固定宽度
	 * @param   Attr:
	 *          [7]:   1消零，0补零
	 *          [5-4]: 小数点位数
	 *          [2-0]: 十进制结果位数,x+1位
	 *****************************************************************************/
	void i16_to_ascii(int16_t Num, uint8_t Attr, uint8_t *Des);
	void u16_to_ascii(uint16_t Num, uint8_t Attr, uint8_t *Des);

	/*****************************************************************************
	 * des 目标缓冲， ival 输入值
	 * ipn [7:4]整数位数（包含符号），[3:0]小数位数(不包含小数点)
	 * attr [bit0] 清头零，[bit1]清尾零 ，[bit2]对于小数，尾清零时至少保持一位小数
	 *      [bit4] 强制显示符号 [bit5]右对齐，强制取消尾部清零
	 *****************************************************************************/
	uint8_t i32_to_string(void *des, int32_t ival, uint8_t ip_n, uint8_t attr);

	/*****************************************************************************
	 * src 字符串 p_n小数位数
	 *****************************************************************************/
	int32_t string_to_i32(void const *src, uint8_t p_n);

	/*****************************************************************************
	 * src 字符串转float， 整数部分最大2^31，小数部分截取前9位(DEC)
	 *****************************************************************************/
	float str_to_float(const void *src);

	/*****************************************************************************
	 *          转换结果左对齐
	 * @param   Attr:
	 *          [5-4]: 小数点位数
	 *****************************************************************************/
	uint8_t u16_to_string(uint16_t Num, uint8_t Attr, uint8_t *Des);
	uint8_t i16_to_string(int16_t Num, uint8_t Attr, uint8_t *Des);

	/*******************************************************************************
	 * @brief  i16_to_led_code
	 * \param[in] Data : -1999 至 9999
	 * \param[in] Des  : 4位输出代码
	 * \param[in] zero_clr  : 控制是否清零
	 * \param[in] PointSite : 小数点位置
	 * \param[in] nodisp : 隐藏位控制，bit[7]控制是否隐藏，bit[1:0]指示隐藏的位 0代表个位，3代表千位
	 * \retval: none
	 *******************************************************************************/
	void i16_to_led_code(int16_t Data, uint8_t *Des, uint8_t zero_clr, uint8_t PointSite, uint8_t nodisp);

	/*******************************************************************************
	 * @brief  i16_to_led_code
	 * \param[in] Data : 最大8位数据
	 * \param[in] Des  : 输出代码
	 * \param[in] zero_clr  : 控制是否清零
	 * \param[in] in_ip : in指定有效数据位数，ip指定小数位数
	 * \param[in] nodisp : 隐藏位控制，bit[7]控制是否隐藏，bit[2:0] 隐藏位置
	 * \retval: none
	 *******************************************************************************/
	void i32_to_led_code(int32_t Data, uint8_t *Des, uint8_t zero_clr, uint8_t in_ip, uint8_t nodisp);

	/*******************************************************************************
	 * @brief  软件奇偶校验
	 *******************************************************************************/
	uint8_t EvenU8(uint8_t Data);	  // 返回8位数据的偶校验结果，0表示偶数个1，1表示奇数个1
	uint8_t OddU8(uint8_t Data);	  // 返回8位数据的奇校验结果，0表示奇数个1，0表示偶数个1
	uint8_t NoneParity(uint8_t Data); // 返回8位数据的奇校验结果
#define even_u8 EvenU8
#define odd_u8 OddU8
#define parity_none NoneParity

	/*****************************************************************************
	 * @brief  计算累加和.
	 * \param[in] dat    源数据
	 * \param[in] Len    源数据元素数量
	 * \retval: 和结果
	 *****************************************************************************/
	int32_t sum_i32(const void *dat, uint32_t len); // len 指定元素数量
	int32_t sum_i16(const void *dat, uint32_t len);
	int32_t sum_i8(const void *dat, uint32_t len);
	uint32_t sum_u32(const void *dat, uint32_t len);
	uint32_t sum_u16(const void *dat, uint32_t len);
	uint32_t sum_u8(const void *dat, uint32_t len);

	/*******************************************************************************
	 * @brief  数据舍入
	 *******************************************************************************/
	int32_t sub2_add8(float f_real, int32_t i_now);				   // 二舍八入
	int32_t sub_add_x(float f_real, int32_t i_now, float val_sub); // 自由舍入，舍入值val_sub[0.1-0.49]
	int32_t int_sub2_add8(int32_t real, int32_t i_now);
	int32_t int_sub_add_x(int32_t real, int32_t i_now, int32_t val_sub);

	/*******************************************************************************
	 * @brief  组运算
	 *******************************************************************************/
	/*lrc = ~sum(list)+1 */
	uint8_t lrc_u8(const void *dat, uint32_t len);	 // len 指定元素数量
	uint16_t lrc_u16(const void *dat, uint32_t len); // len 指定元素数量
	uint32_t lrc_u32(const void *dat, uint32_t len); // len 指定元素数量

	/*xor =  0 xor (list) */
	uint8_t xor_u8(const void *dat, uint32_t len);	 // len 指定元素数量
	uint16_t xor_u16(const void *dat, uint32_t len); // len 指定元素数量
	uint32_t xor_u32(const void *dat, uint32_t len); // len 指定元素数量

	/*dat add.*/
	void dat_add_u8(void *src, uint8_t dat, uint32_t Len);	 // len 指定元素数量
	void dat_add_u16(void *src, uint16_t dat, uint32_t Len); // len 指定元素数量
	void dat_add_u32(void *src, uint32_t dat, uint32_t Len); // len 指定元素数量
	void dat_sub_u8(void *src, uint8_t dat, uint32_t Len);	 // len 指定元素数量
	void dat_sub_u16(void *src, uint16_t dat, uint32_t Len); // len 指定元素数量
	void dat_sub_u32(void *src, uint32_t dat, uint32_t Len); // len 指定元素数量

	/*****************************************************************************
	 * 数据记录，数据插在当前索引位置
	 * p_list-记录列表，dat-新数据，p_index-索引变量地址， Len列表元素数量
	 *****************************************************************************/
	void record_u8(void *p_list, uint8_t dat, uint16_t *p_index, uint16_t Len);
	void record_u16(void *p_list, uint16_t dat, uint16_t *p_index, uint16_t Len);
	void record_u32(void *p_list, uint32_t dat, uint16_t *p_index, uint16_t Len);

	/*****************************************************************************
	 * 数据记录，新数据插在表头，后续数据后移
	 * p_list-记录列表，dat-新数据, Len列表长度
	 *****************************************************************************/
	void record_in_first_u8(void *vp_list, uint8_t dat, uint16_t Len);
	void record_in_first_u16(void *vp_list, uint16_t dat, uint16_t Len);
	void record_in_first_u32(void *vp_list, uint32_t dat, uint16_t Len);

	/*--获取数据中 二进制1的个数--*/
	int8_t bit1_get(uint32_t dat); // 返回整数中1的个数
	int8_t bit_1_num_get(uint32_t dat, uint8_t start_pos, uint8_t end_pos);
	int8_t bit_0_num_get(uint32_t dat, uint8_t start_pos, uint8_t end_pos);
	uint32_t list_bit_0_num_get(void *list, uint16_t len); // list 为 char
	uint32_t list_bit_1_num_get(void *list, uint16_t len); // list 为 char

	/*--数据按图加减-- des =src1+src2, des=src1-src2*/
	void map_add_u32(const uint32_t *src1, const uint32_t *src2, uint32_t *des, uint32_t len); // len 指定元素数量
	void map_sub_u32(const uint32_t *src1, const uint32_t *src2, uint32_t *des, uint32_t len); // len 指定元素数量
	void map_add_u16(const uint16_t *src1, const uint16_t *src2, uint16_t *des, uint32_t len); // len 指定元素数量
	void map_sub_u16(const uint16_t *src1, const uint16_t *src2, uint16_t *des, uint32_t len); // len 指定元素数量
	void map_add_u8(const uint8_t *src1, const uint8_t *src2, uint8_t *des, uint32_t len);	   // len 指定元素数量
	void map_sub_u8(const uint8_t *src1, const uint8_t *src2, uint8_t *des, uint32_t len);	   // len 指定元素数量

	/*-按图xor-*/
	void map_xor_u8(const uint8_t *src1, const uint8_t *src2, uint8_t *des, uint32_t len);	   // len 指定元素数量
	void map_xor_u16(const uint16_t *src1, const uint16_t *src2, uint16_t *des, uint32_t len); // len 指定元素数量
	void map_xor_u32(const uint32_t *src1, const uint32_t *src2, uint32_t *des, uint32_t len); // len 指定元素数量

	//--灯光渐变控制
	typedef struct
	{
		uint8_t IncCoef; // 32-255 Y
		uint8_t bDir;
		uint16_t min; // Y
		uint16_t max; // Y
		uint16_t out;
		uint16_t min_keep_time_sv; // Y
		uint16_t max_keep_time_sv; // Y
		uint16_t min_keep_time_cnt;
		uint16_t max_keep_time_cnt;
		uint32_t Cal;
	} led_breath_type;
	uint32_t led_breath_handle(led_breath_type *Brj);

	// 状态管理
	typedef struct
	{
		int32_t time_set;	  // Y 计时设定值
		int32_t time_cnt;	  // X 计时值，新的state_req时复位
		int32_t time_remain;  // X 剩余时间
		uint8_t state_now;	  // X 当前状态
		uint8_t state_req;	  // Y 新状态请求
		uint8_t st_new_state; // X 新状态首次运行标记
		uint8_t st_time_end;  // X 计时结束标记
	} state_manage_type;

	void state_manage_handle(state_manage_type *obj, uint8_t time_pulse);
	void state_manage_reset(state_manage_type *obj);

	/*******************************************************************************
	 * @brief  列表数据变化方向
	 *******************************************************************************/
	typedef struct
	{
		// 输入
		const void *dat;   // 数据列表
		uu16 len;		   // 数据长度
		uu16 index_now;	   // 当前位置
		uu16 index_offset; // 前偏移位置
		uu16 cmp_amount;   // 比较个数
		ii16 val_offset;   // 统计上升下降数量的值偏移

		// 输出
		ii16 up_num;  // 上升数据个数，差值大于等于val_offset
		ii16 dn_num;  // 下降数据个数，差值小于等于-val_offset
		ii16 mid_num; // 保持数据个数，差值-val_offset~val_offset
		ii16 cmp_min; // now-fore的最小值，大于0说明上升
		ii16 cmp_max; // now-fore的最大值，小于0说明下降
	} list16_dir_identify_type;

	void list16_dir_identify(list16_dir_identify_type *obj);

	/*******************************************************************************
	 * @brief  列表数据变化方向
	 * \param[in] dat 数据列表
	 * \param[in] len 数据长度
	 * \param[in] index_now : 当前位置
	 * \param[in] index_offset : 前偏移位置
	 * \param[in] amount : 比较个数
	 * \retval: 返回最大值小于0说明下降，返回最小值大于0说明上升
	 *******************************************************************************/
	i32_limit_type list_dir_i32(const void *dat, uu16 len, uu16 index_now, uu16 index_offset, uu16 amount);
	i16_limit_type list_dir_i16(const void *dat, uu16 len, uu16 index_now, uu16 index_offset, uu16 amount);

	/*******************************************************************************
	 * @brief  求模。用区间对指定数据求模，结果在区间内。例 21 % (10,19) = 11; 9 % (10,19) = 19
	 * \param[in] min 范围最小值
	 * \param[in] min 范围最大值
	 * \param[in] dat : 当前位置
	 * \retval: 取模后的数据
	 *******************************************************************************/
	int32_t dat32_rang_mod(int32_t min, int32_t max, int32_t dat);
	int16_t dat16_rang_mod(int16_t min, int16_t max, int16_t dat);

	/*******************************************************************************
	 * @brief  滚动范围内数据 是否在启停范围内
	 * \param[in] min 滚动范围最小值
	 * \param[in] min 滚动范围最大值
	 * \param[in] start : 开始位置
	 * \param[in] end : 结束位置
	 * \param[in] dat : 当前位置
	 * \retval: 结果
	 *******************************************************************************/
	bbool dat16_roll_rang_check(int16_t min, int16_t max, int16_t start, int16_t end, int16_t dat);
	bbool dat32_roll_rang_check(int32_t min, int32_t max, int32_t start, int32_t end, int32_t dat);

	/****************************************************************************
	 * @brief   bit merge
	 * @param   dat bit_num
	 * @return  merge value
	 * @ Pass/ Fail criteria: none
	 *****************************************************************************/
	uint32_t bit32_u8_merge(uint8_t *dat, uint8_t bit_num);
	uint32_t bit32_u16_merge(uint16_t *dat, uint8_t bit_num);
	uint32_t bit32_u32_merge(uint32_t *dat, uint8_t bit_num);

	// rom 自动分块写入
	uu8 rom_write(uu32 addr, uu8 *dat, uu32 len, uu32 blk_size, uu8 (*wr_hal)(uu32, uu8 *, uu32));

	/*******************************************************************************
	 * @brief lag 结构
	 *******************************************************************************/
	typedef struct
	{
		// Y 设置
		ii08 keep_sv; // 数据保持时间，跟进周期
		// X 输出
		ii08 keep_cnt;
		ii16 vlag;
	} lag16_type;

	/*******************************************************************************
	 * @brief? lag，适用于变化缓慢但有干扰的数据
	 * \param[in] lag: 数据对象
	 * \param[in] vin: 实时数据输入
	 * \param[in] rang: 迟滞范围，0表示没有迟滞
	 * \retval: vlag
	 *******************************************************************************/
	ii16 lag16_handle(lag16_type *lag, ii16 vin, ii16 rang);

	/*******************************************************************************
	 * @brief lag 结构
	 *******************************************************************************/
	typedef struct
	{
		// Y 设置
		ii16 keep_sv; // 数据保持时间，跟进周期[1-n]。0和1都视为周期为1，即每个周期都跟进。
		// X 输出
		ii16 keep_cnt;
		ii32 vlag;
	} lag32_type;

	/*******************************************************************************
	 * @brief? lag，适用于变化缓慢但有干扰的数据
	 * \param[in] lag: 数据对象
	 * \param[in] vin: 实时数据输入
	 * \param[in] rang: 迟滞范围，0表示没有迟滞
	 * \retval: vlag
	 *******************************************************************************/
	ii32 lag32_handle(lag32_type *lag, ii32 vin, ii32 rang);

    /*******************************************************************************
    * @brief  clock 定时器时钟频率
    * @param  hz 指定PWM频率，Q15定点数据格式
    * @retval Time in DWORD
    *******************************************************************************/
    div_time_16_type pwm_hz_to_clk(uint32_t clock, uint32_t q15_hz);

    /*******************************************************************************
    * @brief  时间分割显示，用于GUS屏的三段式时间显示。将BIN时间转为两个显示字
    * @param  bin tim
    * @retval dword, 高半字为hhm, 低半字为mss
    *******************************************************************************/
   	dword_tt bintim_to_hhm_mss(uint32_t btim);

#ifdef __cplusplus
}
#endif

#endif /* DATAPROC_H */
